Инструкция была написана под ОС Ubuntu, но команды для остальных unix систем будут похожи.

Что такое Shipitjs?

Shipijs - это средство для удаленного развертывания приложений и автоматизации выполнения команд локально и удаленно на сервере.

Shipit был создан как альтернатива Capistrano для людей, которые не знают Ruby или испытывают сложности при работе с ним.

Установка Shipitjs

Скорее всего, вы знакомы с grunt или gulp. Оба они являются менеджерами сборки задачи, общее у них то, что у обоих есть файл, который используется для определения задач, gruntfile или gulpfile соответственно. Shipit работает точно так же с shipitfile и интерфейсом командной строки.

Перед установкой убедитесь что у вас установлен node.js и NPM, как это сделать можно прочитать здесь: Установка Node.js и NPM в Ubuntu.

Для того чтобы установить shipitjs необходимо выполнить команду в консоле:

$ sudo npm install --global shipit-cli

Установка shipit-deploy:

$ sudo npm install --global shipit-deploy

Обновляем гит до последней актуальной версии. Если не обновить гит, то при доступе к серверам git по ssh в некоторых случаях могут возникать проблемы. Тем более они сами предупреждают об обновлении:

Подключаем к системе репозитории со свежачками гита:

sudo sh -c 'echo "deb http://ppa.launchpad.net/git-core/ppa/ubuntu $(lsb_release -cs) main" > /etc/apt/sources.list.d/git.list'
sudo apt-get update
sudo apt-get upgrade

Если видим ошибку типа:

W: Ошибка GPG: http://ppa.launchpad.net trusty InRelease: Следующие подписи не могут быть проверены, так как недоступен открытый ключ: NO_PUBKEY A1715D88E1DF1F24

Это значит, что ключ у репозитория сменился или у нас такого ключа ранее не было. Запрашиваем его с сервера keyserver.ubuntu.com и обновляем список доступных программ:

sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys A1715D88E1DF1F24
sudo apt-get update
sudo apt-get upgrade

Где A1715D88E1DF1F24 ключ из сообщения об ошибке.

Скрипт для деплоя shipitfile.js

Размещаем в корне проекта файл shipitfile.js, и заполняем его нехитрым кодом.

Если раньше вы работали с grunt или gulp, данный код вам будет знаком, и не составит труда разобраться в нем и создать скрипты деплоя на свое усмотрение.

module.exports = function (shipit) {
    require('shipit-deploy')(shipit);
    shipit.initConfig({
        default: {
            workspace: '/tmp/github-monitor',
            deployTo: '/var/www/site',
            repositoryUrl: 'https://github.com/user/repo.git',
            ignores: ['.git', 'node_modules'],
            keepReleases: 2,
            key: '~/.ssh/id_rsa',
            branch : 'master',
           //shallowClone: true - в моем случае создавало проблемы
        },
        staging: {
            servers: 'user@myserver.com'
        }
    });
};

Запустить деплой очень легко, всего одной командой, ведь ради этого все и делалось. Заходим в консоль, перемещаемся в корень проекта и выполняем:

$ shipit staging deploy

Или для отката:

$ shipit staging rollback

Скрипт скачивает git ветку master в папку /tmp/github-monitor выполняет дополнительные скрипты над кодом, если они есть, и переносится через rsync на сервер myserver.com в папочку /var/www/site.

Переменные которые были использованы в shipitfile.js

  • workspace - директория на локальной машине для подготовки деплоя
  • deployTo - директория на удаленном сервере в которой будет деплой
  • repositoryUrl - url репозитория в котором проект
  • ignores - массив игнорируемых файлов и каталогов при выполнении деплоя
  • keepReleases - количество версий деплоев которые будут хранится на удаленном сервере
  • key - адрес ключей для ssh если у вас ключи в стандартном месте ~/.ssh, эту опцию можно опустить
  • branch - ветка из которой будет собираться деплой
  • staging - название правила для деплоя, в нашем случае для деплоя на user@myserver.com, поддерживает массив адресов

После выполнения на локальной машине у вас создастся папка /tmp/github-monitor, в которой будет подготовлена текущая версия вашего кода.

На удаленном сервере в директории /var/www/site создается ваш деплой.

В директории releases хранятся 5 версий вашего деплоя. А current ссылается всегда на последний деплой.

Если это у вас WEB приложение то DocumentRoot вашего хоста должен ссылаться на current.

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName site.com
    ServerAlias www.site.com
    DocumentRoot /var/www/site/current
    <Directory />
        AllowOverride All
    </Directory>
    <Directory /var/www/site/current>
        Options Indexes FollowSymLinks MultiViews
        AllowOverride all
        Require all granted
    </Directory>
    ErrorLog /var/log/apache2/site-error.log
    LogLevel debug
    CustomLog /var/log/apache2/site-access.log combined
</VirtualHost>

Все, деплой готов к работе ;)

Подводные камни

Когда выполняется деплой, владелец файлов становится тот пользователь под которым вы вошли по SSH. Если ваш web сервер создает временные файлы или по роду деятельности сайта он сохраняет файлы, они получают владельца www-data. И тут начинаются проблемы с выливанием деплоя. Когда у вас уже есть 5 версий деплоя, и вы делаете 6-ю то самая первая версия деплоя должна удалится, но так как в ней есть файлы пользователя www-data это у вас не получится. Решением может быть выполнение деплоя от имени root но это может быть не безопасно в будущем.

Из выше описанного вам должно быть ясно, что если вы через веб интерфейсы сохраняете файлы на сервере то они получают пользователя www-data и остаются в той версии деплоя которая является текущей. Но при следующем деплое в текущем (current) этих файлов уже не будет, т.е. картинки и прочее медиа файлы лучше хранить на уровень выше деплоя.

Дополнительно

Пример настройки нескольких сценариев деплоя.

Файл shipitfile.js:

module.exports = function (shipit) {
    require('shipit-deploy')(shipit);
    shipit.initConfig({
        default: {
            workspace: '/tmp/github-monitor',
            deployTo: '/var/www/site',
            repositoryUrl: 'https://github.com/user/repo.git',
            ignores: ['.git', 'node_modules'],
            keepReleases: 2,
            key: '~/.ssh/id_rsa',
            branch : 'master',
            //shallowClone: true - в моем случае создавало проблемы
        },
        staging: {
            servers: 'user@myserver.com'
        }
        dev: {
            servers: 'user@dev.myserver.com'
            keepReleases: 1,
            deployTo: '/var/www/devSite', 
            branch : 'develop',
        }
    });
};

Заходим в консоль, перемещаемся в корень проекта. И теперь можем сделать деплой на один из серверов (staging или dev).

Выполнить деплой на staging сервер:

shipit staging deploy

Выполнить деплой на dev сервер:

shipit dev deploy